<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>


    <meta http-equiv="content-type" content="text/html; charset=utf-8">
<title>Server-side Pagination and Sorting for Dynamic Data</title>

<style type="text/css">
/*margin and padding on body element
  can introduce errors in determining
  element position and are not recommended;
  we turn them off as a foundation for YUI
  CSS treatments. */
body {
	margin:0;
	padding:0;
}
</style>

<link rel="stylesheet" type="text/css" href="../../build/fonts/fonts-min.css" />
<link rel="stylesheet" type="text/css" href="../../build/paginator/assets/skins/sam/paginator.css" />
<link rel="stylesheet" type="text/css" href="../../build/datatable/assets/skins/sam/datatable.css" />
<script type="text/javascript" src="../../build/yahoo-dom-event/yahoo-dom-event.js"></script>
<script type="text/javascript" src="../../build/connection/connection-min.js"></script>
<script type="text/javascript" src="../../build/json/json-min.js"></script>
<script type="text/javascript" src="../../build/element/element-min.js"></script>
<script type="text/javascript" src="../../build/paginator/paginator-min.js"></script>
<script type="text/javascript" src="../../build/datasource/datasource-min.js"></script>
<script type="text/javascript" src="../../build/event-delegate/event-delegate-min.js"></script>
<script type="text/javascript" src="../../build/datatable/datatable-min.js"></script>

<!--there is no custom header content for this example-->

</head>

<body class="yui-skin-sam">


<h1>Server-side Pagination and Sorting for Dynamic Data</h1>

<div class="exampleIntro">
	<p>This example enables server-side sorting and pagination for data that is
dynamic in nature. The <code>generateRequest</code> config and
<code>doBeforeLoadData()</code> method allow tight integration with changing
values on the server.</p>
			
</div>

<!--BEGIN SOURCE CODE FOR EXAMPLE =============================== -->

<p>Total records (between 0 and 1000): <input type="text" id="total" value="1000"> <input type="button" id="update" value="Update"></p>
<div id="dynamicdata"></div>

<script type="text/javascript">
YAHOO.example.DynamicData = function() {
    // Column definitions
    var myColumnDefs = [ // sortable:true enables sorting
        {key:"id", label:"ID", sortable:true},
        {key:"name", label:"Name", sortable:true},
        {key:"date", label:"Date", sortable:true, formatter:"date"},
        {key:"price", label:"Price", sortable:true},
        {key:"number", label:"Number", sortable:true}
    ];

    // Custom parser
    var timestampToDate = function(oData) {
        // timestamp comes from server in seconds
        // JS needs it in milliseconds
        return new Date(oData*1000);
    };
    
    // DataSource instance
    var myDataSource = new YAHOO.util.DataSource("assets/php/json_proxy.php?");
    myDataSource.responseType = YAHOO.util.DataSource.TYPE_JSON;
    myDataSource.responseSchema = {
        resultsList: "records",
        fields: [
            {key:"id", parser:"number"},
            {key:"name"},
            {key:"date", parser:timestampToDate},
            {key:"price",parser:"number"},
            {key:"number",parser:"number"}
        ],
        // Access to values in the server response
        metaFields: {
            totalRecords: "totalRecords", 
            startIndex: "startIndex"
        }
    };
    
    // Customize request sent to server to be able to set total # of records
    var generateRequest = function(oState, oSelf) {
        // Get states or use defaults
        oState = oState || { pagination: null, sortedBy: null };
        var sort = (oState.sortedBy) ? oState.sortedBy.key : "id";
        var dir = (oState.sortedBy && oState.sortedBy.dir === YAHOO.widget.DataTable.CLASS_DESC) ? "desc" : "asc";
        var startIndex = (oState.pagination) ? oState.pagination.recordOffset : 0;
        var results = (oState.pagination) ? oState.pagination.rowsPerPage : 25;

        var total = YAHOO.util.Dom.get("total").value *1;
        // Validate input
        if(!YAHOO.lang.isNumber(total) || total < 0 || total > 1000) {
            YAHOO.util.Dom.get("total").value = 0;
            total = 0;
            alert("Total must be between 0 and 1000.");
        }

        // Build custom request
        return  "sort=" + sort +
                "&dir=" + dir +
                "&startIndex=" + startIndex +
                "&results=" + (startIndex + results) +
                "&total=" + total;
    };

    // DataTable configuration
    var myConfigs = {
        generateRequest: generateRequest,
        initialRequest: generateRequest(), // Initial request for first page of data
        dynamicData: true, // Enables dynamic server-driven data
        sortedBy : {key:"id", dir:YAHOO.widget.DataTable.CLASS_ASC}, // Sets UI initial sort arrow
        paginator: new YAHOO.widget.Paginator({ rowsPerPage:25 }) // Enables pagination 
    };
    
    // DataTable instance
    var myDataTable = new YAHOO.widget.DataTable("dynamicdata", myColumnDefs, myDataSource, myConfigs);
    // Update totalRecords on the fly with values from server
    myDataTable.doBeforeLoadData = function(oRequest, oResponse, oPayload) {
        oPayload.totalRecords = oResponse.meta.totalRecords;
        oPayload.pagination.recordOffset = oResponse.meta.startIndex;
        return oPayload;
    };

    YAHOO.util.Event.addListener("update", "click", function() {
        myDataSource.sendRequest(generateRequest(), {
            success : myDataTable.onDataReturnSetRows,
            failure : myDataTable.onDataReturnSetRows,
            scope : myDataTable,
            argument: myDataTable.getState() // data payload that will be returned to the callback function
        });
    });

    return {
        ds: myDataSource,
        dt: myDataTable
    };
        
}();
</script>

<!--END SOURCE CODE FOR EXAMPLE =============================== -->

</body>
</html>
